﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Platform.Storage.Redis
{
	public sealed class RedisSetsCommands : RedisCommandsBase
	{
		internal RedisSetsCommands( string setName, RedisMessageChannel channel )
			: base( channel )
		{
			this.SetName = setName;
		}

		public string SetName
		{ get; private set; }



		public int Add( string member )
		{
			return this.Channel.ExecuteInt32( "SADD", this.SetName, member );
		}

		public int Add( params string[] members )
		{
			return this.Channel.ExecuteInt32( "SADD", members.InsertFirst( this.SetName ) );
		}

		public int Count
		{
			get
			{
				return this.Channel.ExecuteInt32( "SCARD", this.SetName );
			}
		}

		public bool Contains( string member )
		{
			return this.Channel.ExecuteInt32( "SISMEMBER", this.SetName, member ) == 1;
		}

		public IEnumerable<string> Intersection( RedisSetsCommands set )
		{
			return this.Intersection( set.SetName );
		}

		public IEnumerable<string> Intersection( params RedisSetsCommands[] sets )
		{
			return this.Intersection( sets.Select( s => s.SetName ).ToArray() );
		}

		public IEnumerable<string> Intersection( params string[] setNames )
		{
			return this.Channel.ExecuteOrQuery( "SINTER", setNames.InsertFirst( this.SetName ) );
		}

		public int IntersectAndStore( string destinationName, params RedisSetsCommands[] sets )
		{
			return this.IntersectAndStore( destinationName, sets.Select( s => s.SetName ).ToArray() );
		}

		public int IntersectAndStore( string destinationName, params string[] setNames )
		{
			return this.Channel.ExecuteInt32( "SINTERSTORE", setNames.InsertFirst( destinationName, this.SetName ) );
		}

		public IEnumerable<string> Union( RedisSetsCommands set )
		{
			return this.Union( set.SetName );
		}

		public IEnumerable<string> Union( params RedisSetsCommands[] sets )
		{
			return this.Union( sets.Select( s => s.SetName ).ToArray() );
		}

		public IEnumerable<string> Union( params string[] setNames )
		{
			return this.Channel.ExecuteOrQuery( "SUNION", setNames.InsertFirst( this.SetName ) );
		}

		public int UnionAndStore( string destinationName, params RedisSetsCommands[] sets )
		{
			return this.UnionAndStore( destinationName, sets.Select( s => s.SetName ).ToArray() );
		}

		public int UnionAndStore( string destinationName, params string[] setNames )
		{
			return this.Channel.ExecuteInt32( "SUNIONSTORE", setNames.InsertFirst( destinationName, this.SetName ) );
		}

		public int Remove( params string[] members )
		{
			return this.Channel.ExecuteInt32( "SREM", members.InsertFirst( this.SetName ) );
		}

		public IEnumerable<string> GetAll()
		{
			return this.Channel.ExecuteOrQuery( "SMEMBERS", this.SetName );
		}
	}
}
